﻿using AntdUI;
using DataTurnClient.Interface;
using DataTurnClient.Model;
using DataTurnClient.ViewModel;
using DynamicData;
using Google.Protobuf.WellKnownTypes;
using HttpLib;
using MetroFramework.Controls;
using ReactiveUI;
using Splat;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Windows.UI.Xaml.Shapes;
using static DataTurnClient.Enum.DType;

namespace DataTurnClient.Control
{
    public partial class JobView : UserControl, IViewFor<JobViewModel>
    {
        object IViewFor.ViewModel
        {
            get => ViewModel;
            set => ViewModel = (JobViewModel)value;
        }

        public JobViewModel ViewModel { get; set; }

        public JobView(ControlType type)
        {
            InitializeComponent();
            InitBindings();
            ViewModel.ControlStatus = type;
            select3.SelectedIndexChanged += Select3_SelectedIndexChanged;
            select2.SelectedIndexChanged += Select2_SelectedIndexChanged;
            input4.TextChanged += Input4_TextChanged;
        }

        private void InitBindings()
        {
            ViewModel = new JobViewModel();
            this.WhenActivated(d =>
            {
                #region 数据绑定

                this.Bind(ViewModel,
                    vm => vm.Job.JobCode,
                    v => v.input3.Text)
                    .DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.Job.JobName,
                    v => v.input1.Text)
                    .DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.Job.JobDetail,
                    v => v.input2.Text)
                    .DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.ErrorMessage,
                    v => v.label9.Text)
                    .DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.Job.JobStatus,
                    v => v.metroCheckBox1.Checked,
                    ConvertBool,
                    ConvertInt
                    )
                    .DisposeWith(d);

                this.badge1.Events().Click.Do(x =>
                {
                    this.Dispose();
                }).Subscribe().DisposeWith(d);

                this.Events().Load.Do(x =>
                {
                    flowPanel1.Controls.Clear();
                    foreach (var st in ViewModel.Weeks)
                    {
                        CreateWeekTag(st);
                    }
                    AntdUI.BaseCollection baseData = new AntdUI.BaseCollection();
                    baseData.AddRange(ViewModel.WeekList.ToArray());
                    select1.Items = baseData;

                    AntdUI.BaseCollection baseDatas = new AntdUI.BaseCollection();
                    baseDatas.AddRange(ViewModel.RequestMode.ToArray());
                    select3.Items = baseDatas;
                    if (!string.IsNullOrEmpty(ViewModel.Job.JobMode))
                    {
                        int index = ViewModel.RequestMode.FindIndex(xxx => xxx == ViewModel.Job.JobMode);
                        ViewModel.Job.JobMode = ViewModel.RequestMode[ViewModel.RequestMode.FindIndex(xxx => xxx == ViewModel.Job.JobMode)];
                        select3.SelectedIndex = index;
                    }

                    AntdUI.BaseCollection baseDatass = new AntdUI.BaseCollection();
                    baseDatass.AddRange(Globals.RouteList.Select(s =>  $"http://{s.Ip}:{s.Port}/{s.Path}").ToList().ToArray() );
                    select2.Items = baseDatass;
                    if (ViewModel.Job != null && !string.IsNullOrEmpty(ViewModel.Job.JobRoute))
                    {
                        string[] route = ViewModel.Job.JobRoute.Split(':');
                        select2.SelectedIndex = int.Parse(route[0]) - 1;
                        //select2.SelectedIndex = route[0];
                        input4.Text = route.Length > 1 ? route[1] : "";
                    }

                    ChangeControlStatus(ViewModel.ControlStatus);
                }).Subscribe().DisposeWith(d);

                this.button3.Events().Click.Do(x =>
                {
                    string weekstring = ViewModel.Job.JobWeek;
                    if (weekstring == "" || weekstring == null)
                    {
                        weekstring = ViewModel.WeekList.FindIndex(xxx => xxx == select1.SelectedValue.ToString()).ToString();
                    }
                    else
                    {
                        weekstring = weekstring + "," + ViewModel.WeekList.FindIndex(xxx => xxx == select1.SelectedValue.ToString()).ToString();
                    }
                    ViewModel.Job.JobWeek = weekstring;
                    CreateWeekTag(select1.SelectedValue.ToString());
                }).Subscribe().DisposeWith(d);

                this.button1.Events().Click.Do(x =>
                {
                    Tag_CloseChanged(null, null);
                    var server = Locator.Current.GetService<ITool>();
                    bool pass = server.CheckControlData(this);
                    if (pass)
                    {
                        var main = Locator.Current.GetService<MainTurnViewModel>();
                        if (ViewModel.ControlStatus == ControlType.Edit)
                        {
                            main.UpdateJobCommand.Execute(ViewModel.Job).Subscribe(result =>
                            {
                                if (!result.Success)
                                {
                                    ViewModel.ErrorMessage = result.Message;
                                }
                                else
                                {
                                    ChangeControlStatus(ControlType.Select);
                                }
                            });
                        }
                        if (ViewModel.ControlStatus == ControlType.Add)
                        {
                            main.AddJobCommand.Execute(ViewModel.Job).Subscribe(result =>
                            {
                                if (!result.Success)
                                {
                                    ViewModel.ErrorMessage = result.Message;
                                }
                                else
                                {
                                    ChangeControlStatus(ControlType.Select);
                                }
                            });
                        }
                    }
                }).Subscribe().DisposeWith(d);

                this.button2.Events().Click.Do(x =>
                {
                    ViewModel.ControlStatus = ControlType.Edit;
                    ChangeControlStatus(ControlType.Edit);

                }).Subscribe().DisposeWith(d);

                ViewModel.WhenAnyValue(vm => vm.Job.JobMode).Do(x =>
                {
                    if (x != null)
                    {
                        int index = ViewModel.RequestMode.FindIndex(xxx => xxx == x);
                        ViewModel.Job.JobMode = ViewModel.RequestMode[ViewModel.RequestMode.FindIndex(xxx => xxx == x)];
                        select3.SelectedIndex = index;
                    }
                }).Subscribe().DisposeWith(d);


                #endregion

                #region 控件只读绑定

                this.Bind(ViewModel,
                    vm => vm.IsRead,
                    v => v.input4.Enabled)
                    .DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.IsRead,
                    v => v.select1.Enabled)
                    .DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.IsRead,
                    v => v.button3.Enabled)
                    .DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.IsRead,
                    v => v.input2.Enabled)
                    .DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.IsRead,
                    v => v.input1.Enabled)
                    .DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.IsRead,
                    v => v.metroCheckBox1.Enabled)
                    .DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.IsRead,
                    v => v.select2.Enabled)
                    .DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.IsRead,
                    v => v.select3.Enabled)
                    .DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.IsRead,
                    v => v.button1.Enabled)
                    .DisposeWith(d);

                #endregion



            });
        }

        private void CreateWeekTag(string value)
        {
            AntdUI.Tag tag = new AntdUI.Tag();
            tag.Size = new Size(38, 33);
            tag.CloseIcon = true;
            tag.Text = value;
            tag.Name = ViewModel.WeekList.FindIndex(xxx => xxx == value).ToString();
            tag.CloseChanged += Tag_CloseChanged;
            flowPanel1.Controls.Add(tag);
        }

        private bool Tag_CloseChanged(object sender, EventArgs e)
        {
            string weekstring = "";
            foreach (AntdUI.Tag control in flowPanel1.Controls)
            {
                if (sender == null || control.Name != (sender as AntdUI.Tag).Name)
                {

                    if (weekstring == "")
                    {
                        weekstring = control.Name;
                    }
                    else
                    {
                        weekstring = weekstring + "," + control.Name;
                    }
                }
            }
            ViewModel.Job.JobWeek = weekstring;
            return true;
        }

        private bool ConvertBool(int num)
        {
            return num > 0;
        }

        private int ConvertInt(bool check)
        {
            return check ? 1:0;
        }

        private void ChangeControlStatus(ControlType type)
        {
            switch (type)
            {
                case ControlType.Add:
                    input3.Enabled = true;
                    ViewModel.IsRead = true;
                    button2.Enabled = false;
                    foreach (var value in ViewModel.WeekList)
                    {
                        CreateWeekTag(value);
                    }
                    break;
                case ControlType.Edit:
                    input3.Enabled = false;
                    ViewModel.IsRead = true;
                    button2.Enabled = false;
                    break;
                case ControlType.Select:
                    input3.Enabled = false;
                    ViewModel.IsRead = false;
                    button2.Enabled = true;
                    foreach (AntdUI.Tag control in flowPanel1.Controls)
                    {
                        control.CloseIcon = false;
                    }
                    break;
                default:
                    input3.Enabled = true;
                    ViewModel.IsRead = false;
                    button2.Enabled = true;
                    break;
            }
        }

        private void Select3_SelectedIndexChanged(object sender, IntEventArgs e)
        {
            if ((sender as AntdUI.Select).SelectedIndex > -1)
            {
                ViewModel.Job.JobMode = ViewModel.RequestMode[(sender as AntdUI.Select).SelectedIndex];
            }
        }

        private void Select2_SelectedIndexChanged(object sender, IntEventArgs e)
        {
            if ((sender as AntdUI.Select).SelectedIndex > -1)
            {
                RouteLine line = Globals.RouteList[(sender as AntdUI.Select).SelectedIndex];

                ViewModel.Job.JobRoute = line.Id+":"+input4.Text;
            }
        }

        private void Input4_TextChanged(object sender, EventArgs e)
        {
            if (select2.SelectedIndex > -1)
            {
                RouteLine line = Globals.RouteList[select2.SelectedIndex];
                ViewModel.Job.JobRoute = line.Id + ":" + (sender as AntdUI.Input).Text;
            }
        }

    }
}
